<template>
    <view class="uni-collapse-item">
        <!-- onClick(!isOpen) -->
        <view
            class="uni-collapse-item__title"
            :class="{ 'is-open': isOpen && titleBorder === 'auto', 'uni-collapse-item-border': titleBorder !== 'none' }"
            @click="onClick(!isOpen)"
        >
            <view class="uni-collapse-item__title-wrap">
                <slot name="title">
                    <view class="uni-collapse-item__title-box" :class="{ 'is-disabled': disabled }">
                        <image v-if="thumb" :src="thumb" class="uni-collapse-item__title-img" />
                        <text class="uni-collapse-item__title-text">{{ title }}</text>
                    </view>
                </slot>
            </view>
            <view
                v-if="showArrow"
                :class="{
                    'uni-collapse-item__title-arrow-active': isOpen,
                    'uni-collapse-item--animation': showAnimation === true
                }"
                class="uni-collapse-item__title-arrow"
            >
                <uni-icons :color="disabled ? '#ddd' : '#bbb'" size="14" type="bottom" />
            </view>
        </view>
        <view
            class="uni-collapse-item__wrap"
            :class="{ 'is--transition': showAnimation }"
            :style="{ height: (isOpen ? height : 0) + 'px' }"
        >
            <view
                :id="elId"
                ref="collapse--hook"
                class="uni-collapse-item__wrap-content"
                :class="{ open: isheight, 'uni-collapse-item--border': border && isOpen }"
            >
                <slot></slot>
            </view>
        </view>
    </view>
</template>

<script>
// #ifdef APP-NVUE
const dom = weex.requireModule("dom");
// #endif
/**
 * CollapseItem 折叠面板子组件
 * @description 折叠面板子组件
 * @property {String} title 标题文字
 * @property {String} thumb 标题左侧缩略图
 * @property {String} name 唯一标志符
 * @property {Boolean} open = [true|false] 是否展开组件
 * @property {Boolean} titleBorder = [true|false] 是否显示标题分隔线
 * @property {String} border = ['auto'|'show'|'none'] 是否显示分隔线
 * @property {Boolean} disabled = [true|false] 是否展开面板
 * @property {Boolean} showAnimation = [true|false] 开启动画
 * @property {Boolean} showArrow = [true|false] 是否显示右侧箭头
 */
export default {
    name: "UniCollapseItem",
    props: {
        // 列表标题
        title: {
            type: String,
            default: ""
        },
        name: {
            type: [Number, String],
            default: ""
        },
        // 是否禁用
        disabled: {
            type: Boolean,
            default: false
        },
        // #ifdef APP-PLUS
        // 是否显示动画,app 端默认不开启动画，卡顿严重
        showAnimation: {
            type: Boolean,
            default: false
        },
        // #endif
        // #ifndef APP-PLUS
        // 是否显示动画
        showAnimation: {
            type: Boolean,
            default: true
        },
        // #endif
        // 是否展开
        open: {
            type: Boolean,
            default: false
        },
        // 缩略图
        thumb: {
            type: String,
            default: ""
        },
        // 标题分隔线显示类型
        titleBorder: {
            type: String,
            default: "auto"
        },
        border: {
            type: Boolean,
            default: true
        },
        showArrow: {
            type: Boolean,
            default: true
        }
    },
    data() {
        // TODO 随机生生元素ID，解决百度小程序获取同一个元素位置信息的bug
        const elId = `Uni_${Math.ceil(Math.random() * 10e5).toString(36)}`;
        return {
            isOpen: false,
            isheight: null,
            height: 0,
            elId,
            nameSync: 0
        };
    },
    watch: {
        open(val) {
            this.isOpen = val;
            this.onClick(val, "init");
        }
    },
    updated(e) {
        this.$nextTick(() => {
            this.init(true);
        });
    },
    created() {
        this.collapse = this.getCollapse();
        this.oldHeight = 0;
        this.onClick(this.open, "init");
    },
    // #ifndef VUE3
    // TODO vue2
    unmounted() {
        if (this.__isUnmounted) return;
        this.uninstall();
    },
    // #endif
    // #ifdef VUE3
    // TODO vue3
    unmounted() {
        this.__isUnmounted = true;
        this.uninstall();
    },
    // #endif
    mounted() {
        if (!this.collapse) return;
        if (this.name !== "") {
            this.nameSync = this.name;
        } else {
            this.nameSync = this.collapse.childrens.length + "";
        }
        if (this.collapse.names.indexOf(this.nameSync) === -1) {
            this.collapse.names.push(this.nameSync);
        } else {
            console.warn(`name 值 ${this.nameSync} 重复`);
        }
        if (this.collapse.childrens.indexOf(this) === -1) {
            this.collapse.childrens.push(this);
        }
        this.init();
    },
    methods: {
        init(type) {
            // #ifndef APP-NVUE
            this.getCollapseHeight(type);
            // #endif
            // #ifdef APP-NVUE
            this.getNvueHwight(type);
            // #endif
        },
        uninstall() {
            if (this.collapse) {
                this.collapse.childrens.forEach((item, index) => {
                    if (item === this) {
                        this.collapse.childrens.splice(index, 1);
                    }
                });
                this.collapse.names.forEach((item, index) => {
                    if (item === this.nameSync) {
                        this.collapse.names.splice(index, 1);
                    }
                });
            }
        },
        onClick(isOpen, type) {
            if (this.disabled) return;
            this.isOpen = isOpen;
            if (this.isOpen && this.collapse) {
                this.collapse.setAccordion(this);
            }
            if (type !== "init") {
                this.collapse.onChange(isOpen, this);
            }
        },
        getCollapseHeight(type, index = 0) {
            const views = uni.createSelectorQuery().in(this);
            views
                .select(`#${this.elId}`)
                .fields(
                    {
                        size: true
                    },
                    (data) => {
                        // TODO 百度中可能获取不到节点信息 ，需要循环获取
                        if (index >= 10) return;
                        if (!data) {
                            index++;
                            this.getCollapseHeight(false, index);
                            return;
                        }
                        // #ifdef APP-NVUE
                        this.height = data.height + 1;
                        // #endif
                        // #ifndef APP-NVUE
                        this.height = data.height;
                        // #endif
                        this.isheight = true;
                        if (type) return;
                        this.onClick(this.isOpen, "init");
                    }
                )
                .exec();
        },
        getNvueHwight(type) {
            const result = dom.getComponentRect(this.$refs["collapse--hook"], (option) => {
                if (option && option.result && option.size) {
                    // #ifdef APP-NVUE
                    this.height = option.size.height + 1;
                    // #endif
                    // #ifndef APP-NVUE
                    this.height = option.size.height;
                    // #endif
                    this.isheight = true;
                    if (type) return;
                    this.onClick(this.open, "init");
                }
            });
        },
        /**
         * 获取父元素实例
         */
        getCollapse(name = "uniCollapse") {
            let parent = this.$parent;
            let parentName = parent.$options.name;
            while (parentName !== name) {
                parent = parent.$parent;
                if (!parent) return false;
                parentName = parent.$options.name;
            }
            return parent;
        }
    }
};
</script>

<style lang="scss">
.uni-collapse-item {
    /* #ifndef APP-NVUE */
    box-sizing: border-box;

    /* #endif */
    &__title {
        /* #ifndef APP-NVUE */
        display: flex;
        width: 100%;
        box-sizing: border-box;
        /* #endif */
        flex-direction: row;
        align-items: center;
        transition: border-bottom-color 0.3s;

        // transition-property: border-bottom-color;
        // transition-duration: 5s;
        &-wrap {
            width: 100%;
            flex: 1;
        }

        &-box {
            padding: 0 15px;
            /* #ifndef APP-NVUE */
            display: flex;
            width: 100%;
            box-sizing: border-box;
            /* #endif */
            flex-direction: row;
            justify-content: space-between;
            align-items: center;
            height: 48px;
            line-height: 48px;
            background-color: #fff;
            color: #303133;
            font-size: 13px;
            font-weight: 500;
            /* #ifdef H5 */
            cursor: pointer;
            outline: none;

            /* #endif */
            &.is-disabled {
                .uni-collapse-item__title-text {
                    color: #999;
                }
            }
        }

        &.uni-collapse-item-border {
            border-bottom: 1px solid #ebeef5;
        }

        &.is-open {
            border-bottom-color: transparent;
        }

        &-img {
            height: 22px;
            width: 22px;
            margin-right: 10px;
        }

        &-text {
            flex: 1;
            font-size: 14px;
            /* #ifndef APP-NVUE */
            white-space: nowrap;
            color: inherit;
            /* #endif */
            /* #ifdef APP-NVUE */
            lines: 1;
            /* #endif */
            overflow: hidden;
            text-overflow: ellipsis;
        }

        &-arrow {
            /* #ifndef APP-NVUE */
            display: flex;
            box-sizing: border-box;
            /* #endif */
            align-items: center;
            justify-content: center;
            width: 20px;
            height: 20px;
            margin-right: 10px;
            transform: rotate(0deg);

            &-active {
                transform: rotate(-180deg);
            }
        }
    }

    &__wrap {
        /* #ifndef APP-NVUE */
        will-change: height;
        box-sizing: border-box;
        /* #endif */
        background-color: #fff;
        overflow: hidden;
        position: relative;
        height: 0;

        &.is--transition {
            // transition: all 0.3s;
            transition-property: height, border-bottom-width;
            transition-duration: 0.3s;
            /* #ifndef APP-NVUE */
            will-change: height;
            /* #endif */
        }

        &-content {
            position: absolute;
            font-size: 13px;
            color: #303133;
            // transition: height 0.3s;
            border-bottom-color: transparent;
            border-bottom-style: solid;
            border-bottom-width: 0;

            &.uni-collapse-item--border {
                border-bottom-width: 1px;
                border-bottom-color: red;
                border-bottom-color: #ebeef5;
            }

            &.open {
                position: relative;
            }
        }
    }

    &--animation {
        transition-property: transform;
        transition-duration: 0.3s;
        transition-timing-function: ease;
    }
}
</style>
